package com.triplelink.builder.query;

import java.lang.reflect.Field;
import java.util.Stack;

import com.triplelink.context.Connector;
import com.triplelink.exception.TripleLinkException;
import com.triplelink.to.steak.InstancePartTO;
import com.triplelink.util.EntityUtil;

public class DeleteQueryBuilder
{
	public static QueryTL build(Object entity, String abox, Connector connector)
	{
		try
		{
			return build(EntityUtil.getIdOrCreate(entity), entity.getClass(), abox, connector);
		}
		catch (IllegalArgumentException e)
		{
			throw new TripleLinkException(e);
		}
		catch (IllegalAccessException e)
		{
			throw new TripleLinkException(e);
		}
	}
	
	public static QueryTL build(String id, Class<?> entityClass, String abox, Connector connector)
	{
		QueryTL deletePart = QueryTL.create(connector);
		QueryTL wherePart = deletePart.shareResources();
		
		try
		{
			deletePart
			.append("WITH <").append(abox).append("> \n")
			.append("DELETE \n")
			.append("{ \n")
			.plusTab();
			
			wherePart
			.append("WHERE \n")
			.append("{ \n")
			.plusTab();
			
			build(id, entityClass, deletePart, wherePart);
			
			deletePart
			.append("} \n");
			
			wherePart
			.append("} \n");
			
			return deletePart.append(wherePart.getSb().toString());
		}
		catch (IllegalArgumentException e)
		{
			throw new TripleLinkException(e);
		}
		catch (IllegalAccessException e)
		{
			throw new TripleLinkException(e);
		}
	}
	
	public static void build(String id, Class<?> entityClass, QueryTL deletePart, QueryTL wherePart) throws IllegalArgumentException, IllegalAccessException
	{
		Stack<InstancePartTO> stack = new Stack<InstancePartTO>();
		
		putFilterId(id, deletePart, wherePart);
		push(id, entityClass, true, stack);
		
		while (!stack.isEmpty())
		{
			InstancePartTO item = stack.pop();
			
			for (Field field : item.getClassEntity().getDeclaredFields())
				putValue(field, item, stack, deletePart, wherePart);
		}
	}
	
	static void putFilterId(String id, QueryTL deletePart, QueryTL wherePart)
	{
		wherePart
		.appendTab()
		.appendUri(id);
	
		String labelProperty = wherePart.appendRandowLabel();
		String labelValue = wherePart.appendRandowLabel();
		
		wherePart.appendEndPoint();

		deletePart
		.appendTab()
		.appendUri(id)
		.appendLabel(labelProperty)
		.appendLabel(labelValue)
		.appendEndPoint();
	}
	
	private static void push(String id, Class<?> entityClass, boolean cascadeSave, Stack<InstancePartTO> stack) throws IllegalArgumentException, IllegalAccessException
	{
		Class<?> currentClass = entityClass;
		
		while (currentClass != null)
		{
			stack.push(new InstancePartTO(id, null, currentClass, cascadeSave));
			
			currentClass = currentClass.getSuperclass();
		}
	}
	
	private static void putValue(Field field, InstancePartTO item, Stack<InstancePartTO> stack, QueryTL deletePart, QueryTL wherePart) throws IllegalArgumentException, IllegalAccessException
	{
		field.setAccessible(true);
		
	}
}